package com.mc.fastkit.dialog

import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.view.Gravity
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.View.SYSTEM_UI_FLAG_FULLSCREEN
import android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
import android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
import android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
import android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
import android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE
import android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
import android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import android.widget.FrameLayout
import androidx.annotation.CallSuper
import androidx.annotation.IdRes
import androidx.annotation.LayoutRes
import androidx.core.graphics.toRectF
import androidx.core.view.forEach
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import androidx.lifecycle.lifecycleScope
import com.mc.fastkit.R
import com.mc.fastkit.dialog.animator.AbsDialogAnimator
import com.mc.fastkit.dialog.animator.AnimatorItem
import com.mc.fastkit.dialog.animator.BgAnimator
import com.mc.fastkit.dialog.animator.ContentAnimator
import com.mc.fastkit.ext.activity
import com.mc.fastkit.ext.cast
import com.mc.fastkit.ext.castOrNull
import com.mc.fastkit.ext.frameLayoutParams
import com.mc.fastkit.ext.getGlobalVisibleRect
import com.mc.fastkit.ext.getLocationOnScreen
import com.mc.fastkit.ext.invisible
import com.mc.fastkit.ext.navigationBarHeight
import com.mc.fastkit.ext.setStartMargin
import com.mc.fastkit.ext.setTopMargin
import com.mc.fastkit.ext.statusBarHeight
import com.mc.fastkit.utils.KeyboardUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.math.pow
import kotlin.math.sqrt


/**
 * XDialog
 * @author: MasterChan
 * @date: 2023-12-19 14:30
 */
@SuppressLint("ClickableViewAccessibility")
@Suppress("DEPRECATION")
abstract class XDialog<T : XDialog<T>>(val context: Context) : IDialog<T>, LifecycleOwner {

    companion object {
        fun new(context: Context, layout: Int): XDialog<SimpleDialog> {
            return SimpleDialog(context, layout)
        }

        fun new(context: Context, contentView: View): XDialog<SimpleDialog> {
            return SimpleDialog(context, view = contentView)
        }
    }

    sealed class State(private val value: Int) {
        data object Idle : State(0)

        /**
         * 正在显示，此时[dialog]已经显示，[Dialog.isShowing]位于true状态，可能正处于显示动画执行阶段
         */
        data object Showing : State(1)

        /**
         * 已经完成显示，此时动画已经执行完毕
         */
        data object Shown : State(2)

        /**
         * 正在隐藏，此时[dialog]还未隐藏，[Dialog.isShowing]位于true状态；正处于隐藏动画执行阶段
         */
        data object Dismissing : State(3)

        /**
         * 已经隐藏，此时已经调用了[Dialog.dismiss]
         */
        data object Dismissal : State(4)

        operator fun minus(state2: State): Int {
            return value - state2.value
        }
    }

    fun interface OnShowListener {
        fun onShow(dialog: XDialog<*>)
    }

    fun interface OnDismissListener {
        fun onDismiss(dialog: XDialog<*>)
    }

    fun interface OnBackPressedListener {
        fun onBackPressed(dialog: XDialog<*>): Boolean
    }

    final override val lifecycle by lazy { LifecycleRegistry(this) }
    override var contentWidth: Int? = null
    override var contentHeight: Int? = null
    override var isDismissOnBackPressed: Boolean = true
    override var isDismissOnTouchOutside: Boolean = true
    override var isHideKeyboardOnTouchOutside: Boolean = true
    override val isUpKeyboard: Boolean = true
    override var isTouchThrough: Boolean = false
    override var offsetX: Int = 0
    override var offsetY: Int = 0
    override var contentAnimator: AbsDialogAnimator? = null
    override var bgAnimator: BgAnimator? = null
    override var animatorDuration: Long = 300
    override var enableAnimator: Boolean = true
    override var bgColor: Int = Color.parseColor("#7F000000")
    override var isBgBlur: Boolean = false
    override var contentGravity: Int = -1
    override var isHideNavigationBar: Boolean = false
    override var isImmersiveNavigationBar: Boolean = false
    override var navigationBarColor: Int = 0
    override var isNavigationBarLight: Boolean? = null
    override var isHideStatusBar: Boolean = false
    override var statusBarColor: Int = Color.TRANSPARENT
    override var isStatusBarLight: Boolean? = null
    override var anchor: View? = null
    override var isOverlayAnchor: Boolean = true
    override var ignoredStatusBar: Boolean = false
    override var ignoredNavigationBar: Boolean = false
    override var tag: String = ""

    protected val container = FrameLayout(context)
    protected var dialog: Dialog? = null
    private var isCreated = false
    private val current = this.cast<T>()
    private val touchSlop = ViewConfiguration.get(context).scaledTouchSlop
    private var lastX = 0f
    private var lastY = 0f
    private var contentAnimItems: MutableList<AnimatorItem>? = null
    private var onShowListener: OnShowListener? = null
    private var onDismissListener: OnDismissListener? = null
    private var onBackPressedListener: OnBackPressedListener? = null

    var contentView: View? = null
        private set
    var state: State = State.Idle
        private set

    init {
        container.setOnTouchListener(::onTouchEvent)
    }

    protected abstract fun onCreate()

    protected open fun setContentView(@LayoutRes layout: Int) {
        setContentView(LayoutInflater.from(context).inflate(layout, container, false))
    }

    protected open fun setContentView(contentView: View) {
        this.contentView = contentView
        container.addView(contentView)
        if (contentGravity == -1) {
            contentGravity = contentView.frameLayoutParams.gravity
        }
    }

    protected open fun onTouchEvent(view: View, event: MotionEvent): Boolean {
        val rect = contentView!!.getGlobalVisibleRect().toRectF()
        if (!rect.contains(event.x, event.y)) {
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    lastX = event.x
                    lastY = event.y
                    if (isTouchThrough) {
                        context.activity?.dispatchTouchEvent(event)
                    }
                }

                MotionEvent.ACTION_MOVE -> {
                    handleTouchOutside()
                    if (isTouchThrough) {
                        context.activity?.dispatchTouchEvent(event)
                    }
                }

                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                    val dx = event.x - lastX
                    val dy = event.y - lastY
                    val distance = sqrt(dx.toDouble().pow(2) + dy.toDouble().pow(2))
                    if (distance < touchSlop) {
                        handleTouchOutside()
                    }
                    if (isTouchThrough) {
                        context.activity?.dispatchTouchEvent(event)
                    }
                    lastX = 0f
                    lastY = 0f
                }
            }
        }
        return true
    }

    /**
     * 处理[contentView]之外的Touch事件
     */
    protected open fun handleTouchOutside() {
        if (isDismissOnTouchOutside) {
            if (isHideKeyboardOnTouchOutside && KeyboardUtils.isShown(dialog!!.window!!)) {
                dialog!!.currentFocus?.let { KeyboardUtils.hideKeyboard(it) }
            } else {
                dismiss()
            }
        } else {
            if (isHideKeyboardOnTouchOutside && KeyboardUtils.isShown(dialog!!.window!!)) {
                dialog!!.currentFocus?.let { KeyboardUtils.hideKeyboard(it) }
            }
        }
    }

    override fun show(tag: String?): T {
        val activity = context.activity
        if (activity == null || activity.isFinishing || activity.isDestroyed) return current
        if (dialog?.isShowing == true) return current
        if (!(state == State.Idle || state == State.Dismissal)) return current

        if (dialog == null) {
            //创建Dialog并初始化一些设置和分发事件
            dialog = Dialog(context, R.style.BaseDialog)
            dialog!!.setContentView(container)
            dialog!!.window!!.setBackgroundDrawable(ColorDrawable(0))
            dialog!!.setOnKeyListener { _, keyCode, keyEvent -> onKeyEvent(keyCode, keyEvent) }
            dialog!!.setOnShowListener(::onShowInternal)
        }

        this.tag = tag ?: toString()
        if (!isCreated) {
            isCreated = true
            dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
            onCreate()
            lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
            KeyboardUtils.registerOnKeyboardChangedListener(dialog!!.window!!, ::onKeyboardChanged)
        }
        setSystemBars(dialog!!.window!!)
        initContentView()
        dialog!!.show()
        return current
    }

    /**
     * 设置状态栏和底部导航栏
     * @param window Window
     */
    protected open fun setSystemBars(window: Window) {
        setStatusBar(window)
        setNavigationBar(window)
    }

    /**
     * 设置状态栏；ContainerView延伸至状态栏，并设置状态栏颜色和模式
     * @param window Window
     */
    protected open fun setStatusBar(window: Window) {
        if (isHideStatusBar) {
            hideStatusBar(window)
            return
        }
        val decorView = window.decorView
        //设置ContainerView延伸至状态栏
        val option = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or SYSTEM_UI_FLAG_LAYOUT_STABLE
        decorView.systemUiVisibility = option
        val attrs = window.attributes!!
        attrs.flags = attrs.flags and WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS.inv()
        window.attributes = attrs
        //设置状态栏颜色模式
        val visibility = decorView.systemUiVisibility
        decorView.systemUiVisibility = when (isStatusBarLight) {
            true -> visibility or SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
            false -> visibility and SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
            else -> visibility
        }
        //设置状态栏颜色
        window.statusBarColor = statusBarColor
    }

    /**
     * 设置底部导航栏
     * @param window Window
     */
    protected open fun setNavigationBar(window: Window) {
        if (isHideNavigationBar) {
            hideNavigationBar(window)
            return
        }
        val decorView = window.decorView
        var visibility = decorView.systemUiVisibility
        //设置ContainerView延伸至导航栏
        if (isImmersiveNavigationBar) {
            decorView.systemUiVisibility = visibility or
                    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
                    WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
        }
        //设置导航栏颜色模式
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            visibility = decorView.systemUiVisibility
            decorView.systemUiVisibility = when (isNavigationBarLight) {
                true -> visibility or SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
                false -> visibility and SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv()
                else -> visibility
            }
        }
        window.navigationBarColor = navigationBarColor
    }

    /**
     * 隐藏状态栏
     * @param window Window
     */
    protected open fun hideStatusBar(window: Window) {
        val decorView = window.decorView
        val options = SYSTEM_UI_FLAG_LAYOUT_STABLE or SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
                SYSTEM_UI_FLAG_FULLSCREEN
        decorView.systemUiVisibility = decorView.systemUiVisibility or options
    }

    /**
     * 隐藏底部导航栏
     * @param window Window
     */
    protected open fun hideNavigationBar(window: Window) {
        val decorView = window.decorView as ViewGroup
        decorView.forEach {
            if (it.id != View.NO_ID) {
                val entryName = runCatching {
                    context.resources.getResourceEntryName(it.id)
                }.getOrDefault("")
                if ("navigationBarBackground" == entryName) it.invisible()
            }
        }
        val options = SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or SYSTEM_UI_FLAG_HIDE_NAVIGATION or
                SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        decorView.systemUiVisibility = decorView.systemUiVisibility or options
    }

    protected open fun initContentView() {
        require(contentView != null) {
            "contentView is null,call setContentView() in onCreate() first"
        }
        val params = contentView!!.layoutParams as FrameLayout.LayoutParams
        contentWidth?.let { params.width = it }
        contentHeight?.let { params.height = it }
        contentView!!.layoutParams = params
        if (anchor == null) {
            params.gravity = contentGravity
            contentView!!.translationX = offsetX.toFloat()
            contentView!!.translationY = offsetY.toFloat()
        } else {
            params.gravity = Gravity.NO_GRAVITY
            contentView!!.translationX = 0f
            contentView!!.translationY = 0f
        }
        //先隐藏ContentView，防止跳闪
        contentView!!.alpha = 0f
    }

    protected open fun onKeyboardChanged(isShown: Boolean, height: Int) {
        if (isUpKeyboard) {
            if (isShown) {
                val bottom = contentView!!.y + contentView!!.height
                val navigationBarHeight = if (isHideNavigationBar) context.navigationBarHeight else 0
                if (bottom + height + navigationBarHeight > container.height) {
                    contentView!!.animate()
                        .setDuration(250)
                        .translationY(
                            container.height - (bottom + height + navigationBarHeight) + offsetY
                        )
                        .start()
                }
            } else {
                contentView!!.animate().setDuration(250).translationY(offsetY.toFloat()).start()
            }
        }
    }

    /**
     * 按键事件监听，由[dialog]分发
     * @param keyCode Int
     * @param keyEvent KeyEvent
     * @return Boolean
     */
    protected open fun onKeyEvent(keyCode: Int, keyEvent: KeyEvent): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.action == KeyEvent.ACTION_UP) {
            return when {
                onBackPressedListener?.onBackPressed(current) == true || onBackPressed() -> true
                !KeyboardUtils.isShown(dialog!!.window!!) -> {
                    if (isDismissOnBackPressed) dismiss()
                    true
                }

                else -> false
            }
        }
        return false
    }

    /**
     * 返回键事件监听，其优先级低于[onBackPressedListener]，[onBackPressedListener]返回false，
     * [onBackPressed]会接收到事件，反之不会接收到事件
     *
     * @return Boolean
     */
    protected open fun onBackPressed(): Boolean {
        return false
    }

    /**
     * 真正的dialog显示时调用
     * @param dialog DialogInterface
     */
    protected open fun onShowInternal(dialog: DialogInterface) {
        anchor?.let { setContentLocationWhenAnchor() }
        onStart()
        lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START)
        XDialogManager.instance.onShow(this)
    }

    /**
     * 设置有锚点时的[contentView]位置
     */
    protected open fun setContentLocationWhenAnchor() {
        val anchorPoint = anchor!!.getLocationOnScreen()
        var x: Int
        var y: Int
        when (contentGravity) {
            Gravity.TOP -> {
                x = anchorPoint.x + offsetX
                y = anchorPoint.y - contentView!!.height + offsetY
                if (isOverlayAnchor) {
                    if (contentView!!.width + x > container.width) {
                        x = container.width - contentView!!.width
                    }
                    x = x.coerceAtLeast(0)
                    y = if (!ignoredStatusBar && !isHideStatusBar) {
                        y.coerceAtLeast(context.statusBarHeight)
                    } else {
                        y.coerceAtLeast(0)
                    }
                }
            }

            Gravity.START -> {
                x = anchorPoint.x - contentView!!.width + offsetX
                y = anchorPoint.y + offsetY
                if (isOverlayAnchor) {
                    x = x.coerceAtLeast(0)
                    if (!ignoredNavigationBar && !isHideNavigationBar && isImmersiveNavigationBar) {
                        if (contentView!!.height + y > container.height - context.navigationBarHeight) {
                            y = container.height - contentView!!.height - context.navigationBarHeight
                        }
                    } else {
                        if (contentView!!.height + y > container.height) {
                            y = container.height - contentView!!.height
                        }
                    }
                    y = if (!ignoredStatusBar && !isHideStatusBar) {
                        y.coerceAtLeast(context.statusBarHeight)
                    } else {
                        y.coerceAtLeast(0)
                    }
                }
            }

            Gravity.END -> {
                x = anchorPoint.x + anchor!!.width + offsetX
                y = anchorPoint.y + offsetY
                if (isOverlayAnchor) {
                    if (contentView!!.width + x > container.width) {
                        x = container.width - contentView!!.width
                    }
                    x = x.coerceAtLeast(0)
                    if (!ignoredNavigationBar && !isHideNavigationBar && isImmersiveNavigationBar) {
                        if (contentView!!.height + y > container.height - context.navigationBarHeight) {
                            y = container.height - contentView!!.height - context.navigationBarHeight
                        }
                    } else {
                        if (contentView!!.height + y > container.height) {
                            y = container.height - contentView!!.height
                        }
                    }
                    y = if (!ignoredStatusBar && !isHideStatusBar) {
                        y.coerceAtLeast(context.statusBarHeight)
                    } else {
                        y.coerceAtLeast(0)
                    }
                }
            }

            else -> {
                x = anchorPoint.x + offsetX
                y = anchorPoint.y + anchor!!.height + offsetY
                if (isOverlayAnchor) {
                    if (contentView!!.width + x > container.width) {
                        x = container.width - contentView!!.width
                    }
                    x = x.coerceAtLeast(0)
                    if (!ignoredNavigationBar && !isHideNavigationBar && isImmersiveNavigationBar) {
                        if (contentView!!.height + y > container.height - context.navigationBarHeight) {
                            y = container.height - contentView!!.height - context.navigationBarHeight
                        }
                    } else {
                        if (contentView!!.height + y > container.height) {
                            y = container.height - contentView!!.height
                        }
                    }
                }
            }
        }
        contentView!!.setStartMargin(x)
        contentView!!.setTopMargin(y)
    }

    @CallSuper
    protected open fun onStart() {
        state = State.Showing
        onInitAnimator()
        if (enableAnimator) {
            //如果没有Alpha动画，手动将Alpha置为1
            val animatorItems = contentAnimator.castOrNull<ContentAnimator>()?.animatorItems
            if (animatorItems?.contains(AnimatorItem.Alpha) != true) {
                contentView?.alpha = 1f
            }
            bgAnimator!!.show { onShowAnimator() }
            contentAnimator?.show()
        } else {
            contentView?.alpha = 1f
            container.setBackgroundColor(bgColor)
            onShowAnimator()
        }
    }

    /**
     * 动画初始化，动画包含背景动画和ContentView的动画；如果未自定义ContentView动画，则使用默认动画，
     * 默认动画会根据[contentGravity]的方向设置不同的动画
     */
    protected open fun onInitAnimator() {
        //初始化背景动画
        if (bgAnimator == null) {
            bgAnimator = BgAnimator()
        }
        bgAnimator!!.target = container
        bgAnimator!!.duration = animatorDuration
        bgAnimator!!.bgColor = bgColor
        bgAnimator!!.init()

        //初始化内容动画
        if (contentAnimator == null) {
            contentAnimator = ContentAnimator()
            contentAnimator
        }
        contentAnimator!!.target = contentView
        contentAnimator!!.duration = animatorDuration
        contentAnimator!!.init()

        //设置默认内容动画
        if (contentAnimator is ContentAnimator) {
            val animator = contentAnimator as ContentAnimator
            if (contentAnimItems == null) {
                animator.clearAnimatorItems()
                when {
                    contentGravity and Gravity.VERTICAL_GRAVITY_MASK == Gravity.TOP -> {
                        if (anchor == null) {
                            animator.addAnimatorItem(AnimatorItem.Translate.Top)
                        } else {
                            animator.addAnimatorItem(AnimatorItem.Alpha)
                            animator.addAnimatorItem(AnimatorItem.Scroll.Bottom)
                        }
                    }

                    contentGravity == Gravity.CENTER -> {
                        if (anchor == null) {
                            animator.addAnimatorItem(AnimatorItem.Alpha)
                            animator.addAnimatorItem(AnimatorItem.Scale.Center)
                        }
                    }

                    contentGravity and Gravity.VERTICAL_GRAVITY_MASK == Gravity.BOTTOM -> {
                        if (anchor == null) {
                            animator.addAnimatorItem(AnimatorItem.Translate.Bottom)
                        } else {
                            animator.addAnimatorItem(AnimatorItem.Alpha)
                            animator.addAnimatorItem(AnimatorItem.Scroll.Top)
                        }
                    }

                    contentGravity == Gravity.START -> {
                        if (anchor != null) {
                            animator.addAnimatorItem(AnimatorItem.Alpha)
                            animator.addAnimatorItem(AnimatorItem.Scroll.Right)
                        }
                    }

                    contentGravity == Gravity.END -> {
                        if (anchor != null) {
                            animator.addAnimatorItem(AnimatorItem.Alpha)
                            animator.addAnimatorItem(AnimatorItem.Scroll.Left)
                        }
                    }
                }
            } else {
                animator.setAnimatorItems(contentAnimItems!!)
            }
        }
    }

    protected open fun onShowAnimator() {
        state = State.Shown
        onShowListener?.onShow(current)
        onResume()
        lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
    }

    protected open fun onResume() {}

    override fun dismiss(delay: Long) {
        lifecycleScope.launch {
            withContext(Dispatchers.IO) { delay(delay) }
            if (state == State.Dismissing || state == State.Dismissal) return@launch

            state = State.Dismissing
            onPause()
            lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
            if (enableAnimator) {
                if (bgAnimator != null) {
                    bgAnimator!!.dismiss { dismissInternal() }
                } else {
                    dismissInternal()
                }
                contentAnimator?.dismiss()
            } else {
                contentView?.alpha = 1f
                dismissInternal()
            }
        }
    }

    private fun dismissInternal() {
        state = State.Dismissal
        if (context.activity?.isDestroyed == true) {
            return
        } else {
            dialog?.dismiss()
        }
        onDismissListener?.onDismiss(current)
        onStop()
        lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
        XDialogManager.instance.onDismiss(this)
    }

    protected open fun onPause() {}

    @CallSuper
    protected open fun onStop() {
        context.activity?.let { KeyboardUtils.unregisterOnKeyboardChangedListener(it) }
        tryRemoveFragments()
    }

    override fun update(x: Int, y: Int): T {
        contentView ?: return current
        contentView!!.translationX += x.toFloat()
        contentView!!.translationY += y.toFloat()
        return current
    }

    protected open fun tryRemoveFragments() {
        if (context is FragmentActivity) {
            val manager = context.supportFragmentManager
            val fragments = manager.fragments
            val fragmentNames = getFragmentNames()
            if (fragments.size > 0 && !fragmentNames.isNullOrEmpty()) {
                fragments.forEachIndexed { index, fragment ->
                    if (fragmentNames.contains(fragment.javaClass.simpleName)) {
                        manager.beginTransaction()
                            .remove(fragments[index])
                            .commitAllowingStateLoss()
                    }
                }
            }
        }
    }

    protected open fun getFragmentNames(): List<String>? {
        return null
    }

    protected fun <T : View> findViewById(@IdRes id: Int): T {
        return container.findViewById(id)
    }

    fun setContentAnimator(item: AnimatorItem): T {
        if (contentAnimItems == null) {
            contentAnimItems = mutableListOf(item)
        } else {
            contentAnimItems?.clear()
            contentAnimItems?.add(item)
        }
        return this.cast()
    }

    fun setContentAnimator(items: List<AnimatorItem>): T {
        if (contentAnimItems == null) {
            contentAnimItems = ArrayList(items)
        } else {
            contentAnimItems?.clear()
            contentAnimItems?.addAll(items)
        }
        return this.cast()
    }

    fun setOnShowListener(onShowListener: OnShowListener): T {
        this.onShowListener = onShowListener
        return current
    }

    fun setOnDismissListener(onDismissListener: OnDismissListener): T {
        this.onDismissListener = onDismissListener
        return current
    }

    fun setOnBackPressedListener(onBackPressedListener: OnBackPressedListener): T {
        this.onBackPressedListener = onBackPressedListener
        return current
    }
}